package cn.hls.dao.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.CacheMode;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.type.StandardBasicTypes;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;

import cn.hls.dao.BaseDao;
import cn.hls.entity.vo.PageInfo;
import cn.hls.exception.BussinessException;
import cn.hls.until.GenericsUtils;
import cn.hlsconstant.DataAssessEnum;

/**
 * @fileName: BaseDaoImpl.java
 * @descrption: 基类DAO接口实现类
 * @author : yinghui.zhang
 * @Email: uuhui@163.com
 * @date 2015-4-3
 * @version 1.0
 */
@Component("baseDaoImpl")
public class BaseDaoImpl<T> implements BaseDao<T> {
	private Class<T> entityClass = null;
	@Resource(name = "sessionFactory")
	private SessionFactory sessionFactory;

	public Session getSession() {

		return sessionFactory.getCurrentSession();
		 //return sessionFactory.openSession();
	}

	@SuppressWarnings("unchecked")
	public BaseDaoImpl() {
		this.entityClass = (Class<T>) GenericsUtils.getSuperClassGenricType(
				getClass(), 0);
	}

	public Class<T> getEntityClass() {
		return entityClass;
	}

	public void setEntityClass(Class<T> entityClass) {
		this.entityClass = entityClass;
	}

	@Override
	public boolean add(T entity) throws Exception {
		boolean flag = false;
		try {
			getSession().save(entity);
			flag = true;
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new BussinessException(DataAssessEnum.INSERT_ERROR, entity
					.getClass().getSimpleName() + "对象添加数据表失败");
		}
		return flag;
	}

	@Override
	public boolean update(T entity) throws Exception {
		boolean flag = false;
		try {
			getSession().update(entity);
			flag = true;
		} catch (Exception ex) {
			throw new BussinessException(DataAssessEnum.UPDATE_ERROR, entity
					.getClass().getSimpleName() + "对象更新数据表失败");
		}
		return flag;
	}

	@SuppressWarnings("rawtypes")
	@Override
	public void delete(Object entityId, Class clazz) throws Exception {
		getSession().delete(find(Long.valueOf(entityId + ""), clazz));
	}

	@Override
	public void delete(Object entityId) throws Exception {
		try {
			getSession().delete(
					find(Long.valueOf(entityId + ""), this.entityClass));
		} catch (DataAccessException e) {
			throw new BussinessException(DataAssessEnum.DELETE_ERROR, "数据删除失败");
		}
	}

	@SuppressWarnings("rawtypes")
	@Override
	public void delete(Object[] entityIds, Class clazz) throws Exception {
		try {
			for (Object id : entityIds) {
				delete(id, clazz);
			}
		} catch (Exception e) {
			throw new BussinessException(DataAssessEnum.DELETE_ERROR,
					clazz.getSimpleName() + "对象删除失败");
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public T find(Serializable entityId) throws Exception {
		try {
			return (T) getSession().get(this.entityClass, entityId);
		} catch (DataAccessException e) {
			throw new BussinessException(DataAssessEnum.SELECT_ERROR, "对象数据查找失败");
		}
	}
	

	

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public T find(Serializable entityId, Class clazz) throws Exception {
		try {
			return (T) getSession().get(clazz, entityId);
		} catch (DataAccessException e) {
			throw new BussinessException(DataAssessEnum.SELECT_ERROR,
					clazz.getSimpleName() + "对象数据查找失败");
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public PageInfo<T> find(String selectHql, String countHql, Object[] params,
			PageInfo<T> page) throws Exception {
		Session session = getSession();
		Query q = session.createQuery(countHql);
		if (params != null) {
			for (int i = 0; i < params.length; i++) {
				q.setParameter(i, params[i]);
			}
		}
		Long c = Long.valueOf(((Number) q.uniqueResult()).longValue());
		page.setResults(c);
		if (c.longValue() > 0L) {
			q = session.createQuery(selectHql);
			q.setFirstResult(page.getStart());
			q.setMaxResults(page.getLimit());
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					q.setParameter(i, params[i]);
				}
			}
			page.setList(q.list());
		}
		return page;
	}

	public Object find(String hql, Object[] params) throws Exception {
		Session session = getSession();
		try {
			Query query = session.createQuery(hql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					query.setParameter(i, params[i]);
				}
			}
			return query.list();
		} catch (Exception ex) {
		}
		return new ArrayList<Object>();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> findByHql(String hql, Object[] params) {
		try {
			// return getHibernateTemplate().find(hql, params);
			Session session = getSession();
			Query query = session.createQuery(hql);
			if (params != null) {
				for (int i = 0; i < params.length; i++) {
					query.setParameter(i, params[i]);
				}
			}
			return query.list();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return new ArrayList<T>();
	}

	@Override
	public List<T> findByHqlWithCache(String hql, Object[] params)
			throws Exception {
		try {
			/*
			 * getHibernateTemplate().setCacheQueries(true); return
			 * getHibernateTemplate().find(hql, params);
			 */
			getSession().setCacheMode(CacheMode.REFRESH);
			return findByHql(hql, params);
		} catch (Exception e) {
			throw new BussinessException();
		}

	}

	public int executeHQLUpdate(String hql, Object[] values) throws Exception {
		Query queryObject = getSession().createQuery(hql);
		if (values != null) {
			for (int i = 0; i < values.length; i++)
				queryObject.setParameter(i, values[i]);
		}
		return queryObject.executeUpdate();
	}

	public int executeUpdate(String hql) throws Exception {
		return executeHQLUpdate(hql, null);
	}

	public Long countByHql(String hql, Object[] values) throws Exception {
		Query queryObject = getSession().createQuery(hql);
		if (values != null) {
			for (int i = 0; i < values.length; i++)
				queryObject.setParameter(i, values[i]);
		}
		return (Long) queryObject.uniqueResult();
	}

	public List<T> executeSQLQuery(String sql) throws Exception {
		return executeSQLQuery(sql, null);
	}

	@SuppressWarnings("unchecked")
	public List<T> executeSQLQuery(String sql, Object[] values)
			throws Exception {
		SQLQuery queryObject = getSession().createSQLQuery(sql);
		if (values != null) {
			for (int i = 0; i < values.length; i++)
				queryObject.setParameter(i, values[i]);
		}
		return queryObject.list();
	}

	public int executeSQLUpdate(String hql) throws Exception {
		return executeSQLUpdate(hql, null);
	}

	public int executeSQLUpdate(String sql, Object[] values) throws Exception {
		SQLQuery queryObject = getSession().createSQLQuery(sql);
		if (values != null) {
			for (int i = 0; i < values.length; i++)
				queryObject.setParameter(i, values[i]);
		}
		return queryObject.executeUpdate();
	}

	/**
	 * 获取类名
	 * 
	 * @param clazz
	 *            类对象
	 * @return String
	 */
	public static <T> String getEntityName(Class<T> clazz) {
		String entityname = clazz.getSimpleName();
		return entityname;
	}

	public Long getCustomerId()throws Exception{
		try {
			String dateTime=GenericsUtils.dateFormat(new Date(),"yyyyMMdd");
			return Long.parseLong(dateTime+getNextSeq());
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	/**
	 * 获取下一个序列号
	 * @return Object
	 * @throws Exception 获取seq异常
	 */
	private Object getNextSeq()throws Exception{
		String sql="select hibernate_sequence.nextval as id from dual";
		try {
			Query query=getSession().createSQLQuery(sql).addScalar("id",StandardBasicTypes.INTEGER);
			return query.uniqueResult();
		} catch (Exception e) {
			e.printStackTrace();
			throw new BussinessException(DataAssessEnum.SELECT_ERROR, "获取序列号失败!");
		}
	}

}